﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

namespace ToddMcDermid.SSIS
{
    #region CLASS: ReplacingDataConversionConfiguration
    public class ReplacingDataConversionConfiguration : DTSComponentMetaData
    {
        #region Constructor
        public ReplacingDataConversionConfiguration(IDTSComponentMetaData100 componentMetaData)
            : base(componentMetaData, new ReplacingDataConversionInputList(componentMetaData), 
            new ReplacingDataConversionOutputList(componentMetaData), new ReplacingDataConversionCustomPropertyList(componentMetaData))
        { }
        #endregion

        #region Properties
        public new ReplacingDataConversionOutputList Outputs
        {
            get { return base.Outputs as ReplacingDataConversionOutputList; }
        }

        public new ReplacingDataConversionInputList Inputs
        {
            get { return base.Inputs as ReplacingDataConversionInputList; }
        }

        public new ReplacingDataConversionCustomPropertyList CustomProperties
        {
            get { return base.CustomProperties as ReplacingDataConversionCustomPropertyList; }
        }
        #endregion

        #region Validate (detect inconsistencies internal to configuration, and between I/O configuration and metadata)
        public override DTSValidationStatus Validate()
        {
            DTSValidationStatus status = base.Validate();

            if (status == DTSValidationStatus.VS_ISVALID)
            {
                IDTSVirtualInput100 vInput = this.Inputs.Input.GetVirtualInput();
                #region Check that every column has a configuration
                if (vInput.VirtualInputColumnCollection.Count != this.CustomProperties.ColumnConversionConfigs.Count)
                {
                    this.FireError("Input column metadata has changed.  "
                        + "The component is configured for " + this.CustomProperties.ColumnConversionConfigs.Count.ToString() + " columns, "
                        + "but " + vInput.VirtualInputColumnCollection.Count.ToString() + " columns are on the input.");
                    return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                }
                #endregion

                #region Check that configured columns match input definitions
                foreach (IDTSVirtualInputColumn100 vInputColumn in vInput.VirtualInputColumnCollection)
                {
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByInput(vInputColumn.LineageID);
                    if (columnConfig == null)
                    {
                        this.FireError("Input column metadata has changed.  "
                            + "No configuration exists for column '" + vInputColumn.Name + "' (" + vInputColumn.LineageID.ToString() + ")");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                    else if ((columnConfig.WantToOutput && (vInputColumn.UsageType != DTSUsageType.UT_READONLY))
                        || (!columnConfig.WantToOutput && (vInputColumn.UsageType != DTSUsageType.UT_IGNORED)))
                    {
                        this.FireError("Input column metadata has changed.  "
                            + "Column usage type for '" + vInputColumn.Name + "' (" + vInputColumn.LineageID.ToString() + ") is unexpected.");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                    else if (columnConfig.ColumnName != vInputColumn.Name)
                    {
                        this.FireError("Input column name has changed from '" + columnConfig.ColumnName + "' "
                            + "to '" + vInputColumn.Name + "'.");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                    else if ((columnConfig.InDataType != vInputColumn.DataType)
                        || (columnConfig.InLength != vInputColumn.Length)
                        || (columnConfig.InCodePage != vInputColumn.CodePage)
                        || (columnConfig.InPrecision != vInputColumn.Precision)
                        || (columnConfig.InScale != vInputColumn.Scale))
                    {
                        this.FireError("Input column metadata has changed.  "
                            + "Column '" + vInputColumn.Name + "' (" + vInputColumn.LineageID.ToString() + ") "
                            + "was expected as " + DtsDataTypes.SpecificDataTypeTechnicalDescription(columnConfig.InDataType, columnConfig.InLength, columnConfig.InCodePage, columnConfig.InPrecision, columnConfig.InScale)
                            + "but is now " + DtsDataTypes.SpecificDataTypeTechnicalDescription(vInputColumn.DataType, vInputColumn.Length, vInputColumn.CodePage, vInputColumn.Precision, vInputColumn.Scale)
                            + ".");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }

                }
                foreach (IDTSInputColumn100 inputColumn in this.Inputs.Input.InputColumnCollection)
                {
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByInput(inputColumn.LineageID);
                    if ((inputColumn.ErrorRowDisposition != columnConfig.ErrorRowDisposition)
                        || (inputColumn.TruncationRowDisposition != columnConfig.TruncationRowDisposition))
                    {
                        this.FireError("Column '" + columnConfig.ColumnName + "' "
                            + "(" + columnConfig.InLineageID.ToString() + ") error handling in the data flow doesn't match "
                            + "what is specified in the component.");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                }
                #endregion

                #region Validate the outputs
                #region Check column counts
                if (this.Outputs.Standard.OutputColumnCollection.Count != this.CustomProperties.ColumnConversionConfigs.CountWantToOutput)
                {
                    this.FireError("Output column metadata has changed.  "
                        + "The component expects " + this.CustomProperties.ColumnConversionConfigs.CountWantToOutput.ToString() + " columns "
                        + "on the '" + this.Outputs.Standard.Name + "' output,  "
                        + "but " + this.Outputs.Standard.OutputColumnCollection.Count.ToString() + " columns exist.");
                    return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                }
                if ((this.Outputs.Error.OutputColumnCollection.Count - 2) != this.CustomProperties.ColumnConversionConfigs.Count)
                {
                    this.FireError("Output column metadata has changed.  "
                        + "The component expects " + this.CustomProperties.ColumnConversionConfigs.Count.ToString() + " columns "
                        + "on the '" + this.Outputs.Error.Name + "' output,  "
                        + "but " + this.Outputs.Error.OutputColumnCollection.Count.ToString() + " columns exist.");
                    return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                }
                #endregion

                #region Check that conversions are legal
                bool noColumnsConverted = true;
                ColumnConversionConfig.ConversionValidationResultType worstConversionProblem = ColumnConversionConfig.ConversionValidationResultType.Valid;
                foreach (ColumnConversionConfig columnConfig in this.CustomProperties.ColumnConversionConfigs)
                {
                    if (columnConfig.WantToConvert)
                    {
                        noColumnsConverted = false;
                        if (columnConfig.ConversionValidationResult == ColumnConversionConfig.ConversionValidationResultType.Error)
                        {
                            worstConversionProblem = ColumnConversionConfig.ConversionValidationResultType.Error;
                        }
                        else if (worstConversionProblem == ColumnConversionConfig.ConversionValidationResultType.Valid)
                        {
                            worstConversionProblem = columnConfig.ConversionValidationResult;
                        }
                    }
                }
                if (noColumnsConverted)
                {
                    this.FireWarning("No columns have conversions applied.  Either define some column conversions, "
                        + "or remove the component from the Data Flow to improve performance.");
                }
                if (worstConversionProblem == ColumnConversionConfig.ConversionValidationResultType.Warning)
                {
                    this.FireWarning("Some of the conversions specified may cause truncation or conversion errors.  "
                        + "Review the warnings on each individual column to fix the conversion, or adjust "
                        + "the error and/or truncation error handling on the conversions.");
                }
                else if (worstConversionProblem == ColumnConversionConfig.ConversionValidationResultType.Error)
                {
                    this.FireError("One or more of the conversions specified is not supported.");
                    status = DTSValidationStatus.VS_ISBROKEN;
                }
                #endregion

                #region Check configured columns match output definitions
                foreach (ColumnConversionConfig columnConfig in this.CustomProperties.ColumnConversionConfigs)
                {
                    if (columnConfig.WantToOutput)
                    {
                        IDTSOutputColumn100 outputStandardColumn = null;
                        IDTSOutputColumn100 outputErrorColumn = null;
                        #region Find column on standard output
                        foreach (IDTSOutputColumn100 possibleStandardOutputColumn in this.Outputs.Standard.OutputColumnCollection)
                        {
                            if (columnConfig.OutLineageID == possibleStandardOutputColumn.LineageID)
                            {
                                outputStandardColumn = possibleStandardOutputColumn;
                                break;
                            }
                        }
                        #endregion
                        #region Find column on error output
                        foreach (IDTSOutputColumn100 possibleErrorOutputColumn in this.Outputs.Error.OutputColumnCollection)
                        {
                            if (columnConfig.ErrorLineageID == possibleErrorOutputColumn.LineageID)
                            {
                                outputErrorColumn = possibleErrorOutputColumn;
                                break;
                            }
                        }
                        #endregion
                        #region Report errors if column wasn't found
                        if (outputStandardColumn == null)
                        {
                            this.FireError("Output column '" + columnConfig.ColumnName + "' "
                                + "(" + columnConfig.OutLineageID.ToString() + ") does not exist on the " + this.Outputs.Standard.Name + " output.");
                            return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                        }
                        else if (outputErrorColumn == null)
                        {
                            this.FireError("Output column '" + columnConfig.ColumnName + "' "
                                + "(" + columnConfig.ErrorLineageID.ToString() + ") does not exist on the " + this.Outputs.Error.Name + " output.");
                            return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                        }
                        #endregion
                        #region Detect data type conforms to expectations
                        else
                        {
                            if ((columnConfig.ColumnName != outputStandardColumn.Name)
                                || (columnConfig.OutDataType != outputStandardColumn.DataType)
                                || (columnConfig.OutLength != outputStandardColumn.Length)
                                || (columnConfig.OutCodePage != outputStandardColumn.CodePage)
                                || (columnConfig.OutPrecision != outputStandardColumn.Precision)
                                || (columnConfig.OutScale != outputStandardColumn.Scale))
                            {
                                this.FireError("Output column '" + columnConfig.ColumnName + "' "
                                    + "(" + columnConfig.OutLineageID.ToString() + ") metadata "
                                    + DtsDataTypes.SpecificDataTypeTechnicalDescription(outputStandardColumn.DataType, outputStandardColumn.Length,
                                    outputStandardColumn.CodePage, outputStandardColumn.Precision, outputStandardColumn.Scale)
                                    + " does not match the specified metadata "
                                    + DtsDataTypes.SpecificDataTypeTechnicalDescription(columnConfig.OutDataType, columnConfig.OutLength,
                                    columnConfig.OutCodePage, columnConfig.OutPrecision, columnConfig.OutScale)
                                    + " of the requested conversion.");
                                return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                            }
                            else if ((columnConfig.ColumnName != outputErrorColumn.Name)
                                || (columnConfig.InDataType != outputErrorColumn.DataType)
                                || (columnConfig.InLength != outputErrorColumn.Length)
                                || (columnConfig.InCodePage != outputErrorColumn.CodePage)
                                || (columnConfig.InPrecision != outputErrorColumn.Precision)
                                || (columnConfig.InScale != outputErrorColumn.Scale))
                            {
                                this.FireError("Output error column '" + columnConfig.ColumnName + "' "
                                    + "(" + columnConfig.ErrorLineageID.ToString() + ") metadata "
                                    + DtsDataTypes.SpecificDataTypeTechnicalDescription(outputErrorColumn.DataType, outputErrorColumn.Length,
                                    outputErrorColumn.CodePage, outputErrorColumn.Precision, outputErrorColumn.Scale)
                                    + " does not match the metadata "
                                    + DtsDataTypes.SpecificDataTypeTechnicalDescription(columnConfig.InDataType, columnConfig.InLength,
                                    columnConfig.InCodePage, columnConfig.InPrecision, columnConfig.InScale)
                                    + " of the input column.");
                                return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                            }
                        }
                        #endregion
                    }
                }
                #endregion
                #region Detect extra columns on Standard Output
                foreach (IDTSOutputColumn100 standardOutputColumn in this.Outputs.Standard.OutputColumnCollection)
                {
                    if (this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByOutput(standardOutputColumn.LineageID) == null)
                    {
                        this.FireError("Output column '" + standardOutputColumn.Name + "' "
                            + "(" + standardOutputColumn.LineageID.ToString() + ") should not exist on the " + this.Outputs.Standard.Name + " output.");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                }
                #endregion
                #region Detect extra columns on Error Output
                foreach (IDTSOutputColumn100 errorOutputColumn in this.Outputs.Error.OutputColumnCollection)
                {
                    if ((errorOutputColumn.SpecialFlags == 0) && (this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByError(errorOutputColumn.LineageID) == null))
                    {
                        this.FireError("Output column '" + errorOutputColumn.Name + "' "
                            + "(" + errorOutputColumn.LineageID.ToString() + ") should not exist on the " + this.Outputs.Error.Name + " output.");
                        return DTSValidationStatus.VS_NEEDSNEWMETADATA;
                    }
                }
                #endregion
                #endregion
            }

            return status;
        }
        #endregion

        #region ReinitializeMetaData (repair internal inconsistencies, and make I/O metadata conform to configuration)
        public override void ReinitializeMetaData()
        {
            base.ReinitializeMetaData();

            #region Make configuration match input column metadata
            try
            {
                ColumnConversionConfigList newList = new ColumnConversionConfigList();
                IDTSVirtualInput100 vInput = this.Inputs.Input.GetVirtualInput();
                foreach (IDTSVirtualInputColumn100 vInputColumn in vInput.VirtualInputColumnCollection)
                {
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByInput(vInputColumn.LineageID, vInputColumn.Name);
                    if (columnConfig == null)
                    {
                        columnConfig = new ColumnConversionConfig();
                    }
                    newList.Add(columnConfig);
                    columnConfig.SetInput(vInputColumn.LineageID, vInputColumn.Name);
                    columnConfig.SetInputDataType(vInputColumn.DataType, vInputColumn.Length, vInputColumn.CodePage, vInputColumn.Precision, vInputColumn.Scale);
                    if (columnConfig.WantToOutput && (vInputColumn.UsageType != DTSUsageType.UT_READONLY))
                    {
                        vInput.SetUsageType(columnConfig.InLineageID, DTSUsageType.UT_READONLY);
                    }
                    else if (!columnConfig.WantToOutput && (vInputColumn.UsageType != DTSUsageType.UT_IGNORED))
                    {
                        vInput.SetUsageType(columnConfig.InLineageID, DTSUsageType.UT_IGNORED);
                    }
                }
                this.CustomProperties.ColumnConversionConfigs = newList;
            }
            #region catch ...
            catch (Exception ex)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
                this.FireError("Error in ReinitializeMetaData attempting to repair input metadata: " + ex.Message);
            }
            #endregion
            try
            {
                foreach (IDTSInputColumn100 inputColumn in this.Inputs.Input.InputColumnCollection)
                {
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByInput(inputColumn.LineageID);
                    if (inputColumn.ErrorRowDisposition != columnConfig.ErrorRowDisposition)
                    {
                        inputColumn.ErrorRowDisposition = columnConfig.ErrorRowDisposition;
                    }
                    if (inputColumn.TruncationRowDisposition != columnConfig.TruncationRowDisposition)
                    {
                        inputColumn.TruncationRowDisposition = columnConfig.TruncationRowDisposition;
                    }
                }
            }
            #region catch ...
            catch (Exception ex)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
                this.FireError("Error in ReinitializeMetaData attempting to repair input error disposition metadata: " + ex.Message);
            }
            #endregion
            #endregion

            #region Make output columns match configuration
            #region Remove standard output columns with unknown lineages or those that aren't wanted
            try
            {
                for (int index = (this.Outputs.Standard.OutputColumnCollection.Count - 1); index >= 0; index--)
                {
                    IDTSOutputColumn100 outputColumn = this.Outputs.Standard.OutputColumnCollection[index];
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByOutput(outputColumn.LineageID);
                    if ((columnConfig == null) || (!columnConfig.WantToOutput))
                    {
                        this.Outputs.Standard.OutputColumnCollection.RemoveObjectByIndex(index);
                    }
                }
            }
            #region catch ...
            catch
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
            #endregion
            #endregion
            #region Remove error output columns with unknown lineages
            try
            {
                for (int index = (this.Outputs.Error.OutputColumnCollection.Count - 1); index >= 0; index--)
                {
                    IDTSOutputColumn100 outputColumn = this.Outputs.Error.OutputColumnCollection[index];
                    ColumnConversionConfig columnConfig = this.CustomProperties.ColumnConversionConfigs.FindColumnConfigByError(outputColumn.LineageID);
                    if ((outputColumn.SpecialFlags == 0) && ((columnConfig == null) || !columnConfig.WantToOutput))
                    {
                        this.Outputs.Error.OutputColumnCollection.RemoveObjectByIndex(index);
                    }
                }
            }
            #region catch ...
            catch
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
            #endregion
            #endregion

            #region Add/configure output columns
            try
            {
                foreach (ColumnConversionConfig columnConfig in this.CustomProperties.ColumnConversionConfigs)
                {
                    IDTSOutputColumn100 outputStandardColumn = null;
                    IDTSOutputColumn100 outputErrorColumn = null;
                    if (columnConfig.WantToOutput)
                    {
                        #region Retrieve (or create) standard output column
                        foreach (IDTSOutputColumn100 possibleOutputColumn in this.Outputs.Standard.OutputColumnCollection)
                        {
                            if (columnConfig.OutLineageID == possibleOutputColumn.LineageID)
                            {
                                outputStandardColumn = possibleOutputColumn;
                                break;
                            }
                        }
                        if (outputStandardColumn == null)
                        {
                            outputStandardColumn = this.Outputs.Standard.OutputColumnCollection.New();
                            columnConfig.OutLineageID = outputStandardColumn.LineageID;
                        }
                        #endregion
                        #region Retrieve (or create) error output column
                        foreach (IDTSOutputColumn100 possibleOutputColumn in this.Outputs.Error.OutputColumnCollection)
                        {
                            if (columnConfig.ErrorLineageID == possibleOutputColumn.LineageID)
                            {
                                outputErrorColumn = possibleOutputColumn;
                                break;
                            }
                        }
                        if (outputErrorColumn == null)
                        {
                            outputErrorColumn = this.Outputs.Error.OutputColumnCollection.New();
                            columnConfig.ErrorLineageID = outputErrorColumn.LineageID;
                        }
                        #endregion
                        outputStandardColumn.Name = columnConfig.ColumnName;
                        outputStandardColumn.SetDataTypeProperties(columnConfig.OutDataType, columnConfig.OutLength, columnConfig.OutPrecision, columnConfig.OutScale, columnConfig.OutCodePage);
                        outputErrorColumn.Name = columnConfig.ColumnName;
                        outputErrorColumn.SetDataTypeProperties(columnConfig.InDataType, columnConfig.InLength, columnConfig.InPrecision, columnConfig.InScale, columnConfig.InCodePage);
                    }
                }
            }
            #region catch ...
            catch
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
            #endregion
            #endregion
            #endregion

            this.CustomProperties.SaveToMetaData();
        }
        #endregion

        #region CLASS: ReplacingDataConversionInputList
        public class ReplacingDataConversionInputList : InputList
        {
            #region Constants
            public const string INPUT_NAME = "Input";
            #endregion

            #region Constructor
            public ReplacingDataConversionInputList(IDTSComponentMetaData100 componentMetaData)
                : base(componentMetaData)
            { }
            #endregion

            #region ExpectedInputNames
            public override string[] ExpectedInputNames
            {
                get { return new string[1] { INPUT_NAME }; }
            }
            #endregion

            #region Validate
            public override DTSValidationStatus Validate()
            {
                DTSValidationStatus status = base.Validate();
                if (status == DTSValidationStatus.VS_ISVALID)
                {
                    #region Check that an input is attached
                    if (!this.Input.IsAttached)
                    {
                        this.FireError("Requires an input to be attached.");
                        return DTSValidationStatus.VS_ISBROKEN;
                    }
                    #endregion
                }

                return status;
            }
            #endregion

            #region ReinitializeMetaData
            public override void ReinitializeMetaData()
            {
                base.ReinitializeMetaData();
                this.Input.HasSideEffects = true;

                IDTSVirtualInput100 vInput = this.Input.GetVirtualInput();
                #region Mark all input columns as used
                try
                {
                    foreach (IDTSVirtualInputColumn100 vColumn in vInput.VirtualInputColumnCollection)
                    {
                        if (vColumn.UsageType != DTSUsageType.UT_READONLY)
                        {
                            vInput.SetUsageType(vColumn.LineageID, DTSUsageType.UT_READONLY);
                        }
                    }
                }
                #region catch ...
                catch
                {
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
                #endregion
                #endregion
            }
            #endregion

            #region Individually Named Inputs
            #region Input
            public IDTSInput100 Input
            {
                get { return base[INPUT_NAME]; }
            }
            #endregion
            #endregion
        }
        #endregion

        #region CLASS: ReplacingDataConversionOutputList
        public class ReplacingDataConversionOutputList : OutputList
        {
            #region Constants
            public const string OUTPUT_NAME = "Output";
            public const string ERROROUTPUT_NAME = "Replacing Data Conversion Error Output";
            #endregion

            #region Constructor
            public ReplacingDataConversionOutputList(IDTSComponentMetaData100 componentMetaData)
                : base(componentMetaData)
            { }
            #endregion

            #region ExpectedOutputNames
            public override string[] ExpectedOutputNames
            {
                get { return new string[2] { OUTPUT_NAME, ERROROUTPUT_NAME} ; }
            }
            #endregion

            #region ReinitializeMetaData
            public override void ReinitializeMetaData()
            {
                base.ReinitializeMetaData();
                this.Standard.SynchronousInputID = 0; // asynchronous, because we need to remove upstream columns
                this.Error.IsErrorOut = true;
                this.Error.SynchronousInputID = 0;
            }
            #endregion

            #region Individually Named Outputs
            #region Standard
            public IDTSOutput100 Standard
            {
                get { return base[OUTPUT_NAME]; }
            }
            #endregion

            #region Error
            public IDTSOutput100 Error
            {
                get { return base[ERROROUTPUT_NAME]; }
            }
            #endregion
            #endregion
        }
        #endregion

        #region CLASS: ReplacingDataConversionCustomPropertyList
        public class ReplacingDataConversionCustomPropertyList : CustomPropertyList
        {
            #region Constants
            private const string PROPERTY_NAME_CONVERSION_DATA = "Column Conversion Data";
            private const string PROPERTY_NAME_WARNINGS_SUPPRESSED = "Warnings Suppressed";
            #endregion

            #region Private Variables
            private bool _columnConversionConfigsLoaded;
            private ColumnConversionConfigList _columnConversionConfigs;
            private bool _warningsSuppressedLoaded;
            private bool _warningsSuppressed;
            #endregion

            #region Constructor
            public ReplacingDataConversionCustomPropertyList(IDTSComponentMetaData100 componentMetaData)
                : base(componentMetaData)
            {
                this._columnConversionConfigsLoaded = false;
                this._columnConversionConfigs = new ColumnConversionConfigList();
                this._warningsSuppressedLoaded = false;
            }
            #endregion

            #region ExpectedCustomPropertyNames
            public override string[] ExpectedCustomPropertyNames
            {
                get { return new string[2] { PROPERTY_NAME_CONVERSION_DATA, PROPERTY_NAME_WARNINGS_SUPPRESSED }; }
            }
            #endregion

            #region SaveToMetaData
            public override void SaveToMetaData()
            {
                this.ColumnConversionConfigsSave();
                this.SuppressWarningsSave();
            }
            #endregion

            #region ColumnConversionConfigs
            public ColumnConversionConfigList ColumnConversionConfigs
            {
                get
                {
                    if (!this._columnConversionConfigsLoaded)
                    {
                        #region Load Column Configuration
                        try
                        {
                            IDTSCustomProperty100 columnConversionConfigProperty = base[PROPERTY_NAME_CONVERSION_DATA];
                            if (columnConversionConfigProperty != null)
                            {
                                StringBuilder stringDefaultValue = new StringBuilder();
                                XmlSerializer serializer = new XmlSerializer(typeof(ColumnConversionConfigList));
                                XmlWriter xmlWriter = XmlWriter.Create(stringDefaultValue);
                                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                                ns.Add("", "");

                                string actualValue = (string)columnConversionConfigProperty.Value;

                                System.IO.StringReader stringReader = new System.IO.StringReader(actualValue);
                                this._columnConversionConfigs = (ColumnConversionConfigList)serializer.Deserialize(stringReader);
                            }
                            else
                            {
                                this._columnConversionConfigs = new ColumnConversionConfigList();
                            }
                        }
                        #region catch ...
                        catch
                        {
                            if (System.Diagnostics.Debugger.IsAttached)
                            {
                                System.Diagnostics.Debugger.Break();
                            }
                        }
                        #endregion
                        this._columnConversionConfigsLoaded = true;
                        #endregion
                    }

                    return this._columnConversionConfigs;
                }
                set
                {
                    if (!this._columnConversionConfigs.Equals(value))
                    {
                        this._columnConversionConfigs = value;
                        this.ColumnConversionConfigsSave();
                    }
                }
            }

            private void ColumnConversionConfigsSave()
            {
                #region Save Column Configuration
                if (this._columnConversionConfigsLoaded)
                {
                    try
                    {
                        IDTSCustomProperty100 columnConversionConfigProperty = base[PROPERTY_NAME_CONVERSION_DATA];
                        if (columnConversionConfigProperty == null)
                        {
                            columnConversionConfigProperty = base.Add(PROPERTY_NAME_CONVERSION_DATA);
                            columnConversionConfigProperty.ContainsID = true;
                        }

                        StringBuilder stringValue = new StringBuilder();
                        XmlSerializer serializer = new XmlSerializer(typeof(ColumnConversionConfigList));
                        XmlWriter xmlWriter = XmlWriter.Create(stringValue);
                        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                        ns.Add("", "");
                        serializer.Serialize(xmlWriter, this._columnConversionConfigs, ns);

                        if ((string)columnConversionConfigProperty.Value != stringValue.ToString())
                        {
                            columnConversionConfigProperty.Value = stringValue.ToString();
                        }
                    }
                    #region catch ...
                    catch
                    {
                        if (System.Diagnostics.Debugger.IsAttached)
                        {
                            System.Diagnostics.Debugger.Break();
                        }
                    }
                    #endregion
                }
                #endregion
            }
            #endregion

            #region SuppressWarnings
            public bool SuppressWarnings
            {
                get
                {
                    if (!this._warningsSuppressedLoaded)
                    {
                        #region Load Warning Suppression
                        IDTSCustomProperty100 warningsSuppressedProperty = base[PROPERTY_NAME_WARNINGS_SUPPRESSED];
                        if (warningsSuppressedProperty != null)
                        {
                            this._warningsSuppressed = (bool)warningsSuppressedProperty.Value;
                        }
                        this._warningsSuppressedLoaded = true;
                        #endregion
                    }
                    return this._warningsSuppressed;
                }
                set
                {
                    if (this._warningsSuppressed != value)
                    {
                        this._warningsSuppressed = value;
                        this.SuppressWarningsSave();
                    }
                }
            }

            private void SuppressWarningsSave()
            {
                #region Save Warning Suppression
                try
                {
                    IDTSCustomProperty100 warningsSuppressedProperty = base[PROPERTY_NAME_WARNINGS_SUPPRESSED];
                    if (warningsSuppressedProperty == null)
                    {
                        warningsSuppressedProperty = this.Add(PROPERTY_NAME_WARNINGS_SUPPRESSED);
                        warningsSuppressedProperty.ContainsID = false;
                    }
                    if ((warningsSuppressedProperty.Value == null) || ((bool)warningsSuppressedProperty.Value != this._warningsSuppressed))
                    {
                        warningsSuppressedProperty.Value = this._warningsSuppressed;
                    }
                }
                #region catch ...
                catch
                {
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
                #endregion
                #endregion
            }
            #endregion
        }
        #endregion
    }
    #endregion
}
